/**
 * 段落生成服务 v2.0 - VConsole兼容版本
 * 负责段落多版本生成、流式输出、版本管理等功能
 */

import { ParagraphStrategy, ParagraphMetrics, OutlineNode } from '@/types/brainstorm';

interface ParagraphGenerationRequest {
  sessionId: string;
  outlineNodeId: string;
  outlineNode: OutlineNode;
  previousContent: string[];
  versionCount: number;
  strategies: ParagraphStrategy[];
}

interface RegenerationAdjustments {
  tone?: 'formal' | 'casual' | 'humorous' | 'professional';
  length?: 'shorter' | 'longer' | 'same';
  focus?: string;
  temperature?: number;
}

interface MixSelection {
  versionIndex: number;
  range: [number, number];
  text: string;
}

/**
 * 段落生成服务类
 */
class ParagraphGeneratorService {
  private baseUrl: string;
  private wsUrl: string;
  private activeConnections: Map<string, WebSocket>;

  constructor() {
    // 使用相对路径，让Vite代理处理
    this.baseUrl = '';
    this.wsUrl = import.meta.env.VITE_BRAINSTORM_WS_URL || 'ws://localhost:8000';
    this.activeConnections = new Map();
    console.log('✅ [Paragraph] Service v2.0 initialized - VConsole compatible');
  }

  /**
   * 生成段落（多版本并发）
   */
  async generateParagraph(
    request: ParagraphGenerationRequest,
    onChunk: (versionIndex: number, chunk: string) => void,
    onComplete: (versionIndex: number, metrics: ParagraphMetrics) => void,
    onError: (versionIndex: number, error: string) => void
  ): Promise<void> {
    const { sessionId, outlineNodeId, outlineNode, previousContent, versionCount, strategies } =
      request;

    console.log('🚀 [Paragraph] Generating paragraph:', {
      outlineNodeId,
      versionCount,
      strategies,
    });

    // 为每个版本策略创建生成任务
    const selectedStrategies = strategies.slice(0, versionCount);

    // 并发调用所有版本
    await Promise.allSettled(
      selectedStrategies.map((strategy, index) =>
        this.generateSingleVersion(
          sessionId,
          outlineNodeId,
          outlineNode,
          previousContent,
          strategy,
          index,
          onChunk,
          onComplete,
          onError
        )
      )
    );

    console.log('✅ [Paragraph] All paragraph generation initiated');
  }

  /**
   * 生成单个版本
   */
  private async generateSingleVersion(
    sessionId: string,
    outlineNodeId: string,
    outlineNode: OutlineNode,
    previousContent: string[],
    strategy: ParagraphStrategy,
    versionIndex: number,
    onChunk: (versionIndex: number, chunk: string) => void,
    onComplete: (versionIndex: number, metrics: ParagraphMetrics) => void,
    onError: (versionIndex: number, error: string) => void
  ): Promise<void> {
    try {
      const prompt = this.buildParagraphPrompt(outlineNode, previousContent, strategy);

      const response = await fetch(`${this.baseUrl}/api/v1/brainstorm/paragraph/stream`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          session_id: sessionId,
          outline_node_id: outlineNodeId,
          version_index: versionIndex,
          strategy,
          prompt,
          context: previousContent.slice(-2), // 最近2段作为上下文
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      // 处理SSE流
      const reader = response.body?.getReader();
      const decoder = new TextDecoder();

      if (!reader) {
        throw new Error('No response body');
      }

      let buffer = '';
      let streamCompleted = false;

      while (true) {
        const { done, value } = await reader.read();

        // 立即检查done标志
        if (done) {
          console.log(`[Paragraph] Stream done for version ${versionIndex}`);
          break;
        }

        // 检查streamCompleted标志
        if (streamCompleted) {
          console.log(`[Paragraph] Stream completed flag set for version ${versionIndex}`);
          break;
        }

        // 检查value是否存在和有效
        if (!value || value.byteLength === 0) {
          continue;
        }

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';

        for (const line of lines) {
          if (!line.trim() || !line.startsWith('data: ')) continue;

          const data = line.slice(6);
          if (data === '[DONE]') {
            streamCompleted = true;
            console.log(`[Paragraph] Received [DONE] for version ${versionIndex}`);
            break;
          }

          try {
            const parsed = JSON.parse(data);

            if (parsed.type === 'chunk') {
              onChunk(versionIndex, parsed.content);
            } else if (parsed.type === 'complete') {
              onComplete(versionIndex, parsed.metrics);
            } else if (parsed.type === 'error') {
              onError(versionIndex, parsed.error);
            }
          } catch (error) {
            const errorMsg = error instanceof Error ? error.message : String(error);
            console.error(`❌ [Paragraph] Failed to parse SSE data: ${errorMsg}`);
          }
        }

        // 在处理完所有行后再次检查streamCompleted
        if (streamCompleted) {
          break;
        }
      }

      console.log(`✅ [Paragraph] Version ${versionIndex} (${strategy}) generated successfully`);
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error);
      console.error(`❌ [Paragraph] Failed to generate version ${versionIndex}: ${errorMsg}`);
      onError(versionIndex, errorMsg);
    }
  }

  /**
   * 构建段落生成提示词
   */
  private buildParagraphPrompt(
    node: OutlineNode,
    previousContent: string[],
    strategy: ParagraphStrategy
  ): string {
    const strategyPrompts: Record<ParagraphStrategy, string> = {
      concise: `用简洁直白的语言写作，控制在150-200字，突出核心要点。避免冗余，直击重点。`,
      detailed: `用详细深入的方式展开，300-400字，提供充分的解释和论证。包含细节和具体说明。`,
      vivid: `用生动形象的语言写作，适当使用比喻、案例等修辞手法，让内容更具感染力和画面感。`,
      'data-driven': `以数据和事实为基础，引用权威来源，用统计数字增强说服力。注重客观性和可信度。`,
      mixed: `综合运用多种写作技巧，平衡简洁与详细、事实与感性。`,
    };

    const context =
      previousContent.length > 0
        ? `\n\n**上文内容**：\n${previousContent.slice(-2).join('\n\n')}`
        : '';

    const mainPointsText =
      node.mainPoints && node.mainPoints.length > 0
        ? `\n\n**要点**：\n${node.mainPoints.map((p) => `- ${p}`).join('\n')}`
        : '';

    const keywordsText =
      node.keywords && node.keywords.length > 0
        ? `\n\n**关键词**：${node.keywords.join('、')}`
        : '';

    return `
# 写作任务

## 章节标题
${node.title}

## 写作策略
${strategyPrompts[strategy]}
${mainPointsText}
${keywordsText}
${context}

## 要求
1. 确保与上文自然衔接
2. 遵循指定的写作策略和风格
3. 内容与章节主题紧密相关
4. 语言流畅，逻辑清晰

请开始撰写本段落内容：
    `.trim();
  }

  /**
   * 生成Mock版本数据（用于演示）
   */
  private generateMockVersions(
    strategies: ParagraphStrategy[],
    node: OutlineNode,
    onChunk: (versionIndex: number, chunk: string) => void,
    onComplete: (versionIndex: number, metrics: ParagraphMetrics) => void,
    onError: (versionIndex: number, error: string) => void
  ): void {
    strategies.forEach((strategy, index) => {
      this.generateMockSingleVersion(strategy, node, index, onChunk, onComplete, onError);
    });
  }

  /**
   * 生成单个Mock版本
   */
  private generateMockSingleVersion(
    strategy: ParagraphStrategy,
    node: OutlineNode,
    versionIndex: number,
    onChunk: (versionIndex: number, chunk: string) => void,
    onComplete: (versionIndex: number, metrics: ParagraphMetrics) => void,
    onError: (versionIndex: number, error: string) => void
  ): void {
    const mockContent = this.generateMockContent(strategy, node);

    // 模拟流式输出
    let charIndex = 0;
    const interval = setInterval(() => {
      if (charIndex >= mockContent.length) {
        clearInterval(interval);
        // 生成完成，返回评分
        const metrics: ParagraphMetrics = {
          relevance: 80 + Math.floor(Math.random() * 15),
          readability: 75 + Math.floor(Math.random() * 20),
          originality: 70 + Math.floor(Math.random() * 25),
          coherence: 85 + Math.floor(Math.random() * 10),
        };
        onComplete(versionIndex, metrics);
        return;
      }

      // 每次输出5-10个字符
      const chunkSize = 5 + Math.floor(Math.random() * 5);
      const chunk = mockContent.slice(charIndex, charIndex + chunkSize);
      onChunk(versionIndex, chunk);
      charIndex += chunkSize;
    }, 100); // 每100ms输出一次
  }

  /**
   * 生成Mock内容
   */
  private generateMockContent(strategy: ParagraphStrategy, node: OutlineNode): string {
    const baseContent = `关于${node.title}，我们需要深入探讨其核心要义。`;

    const strategyContent: Record<ParagraphStrategy, string> = {
      concise: `${baseContent}${node.mainPoints?.[0] || '首先'}，这是一个关键要点。其次，我们需要注意相关的实践应用。通过简洁的表述，可以让读者快速掌握核心概念。总的来说，这个主题具有重要的现实意义。`,

      detailed: `${baseContent}${node.mainPoints?.[0] || '首先'}，让我们详细分析这个问题的各个方面。从理论层面来看，它涉及到多个维度的考量，包括基本原理、应用场景和潜在影响。在实践中，我们可以观察到诸多具体案例，这些案例充分说明了该理论的有效性和适用性。进一步地，我们还需要考虑其在不同环境下的表现差异，以及如何根据具体情况进行调整和优化。综合来看，通过深入理解和灵活运用，我们能够更好地把握其本质特征和实用价值。`,

      vivid: `${baseContent}想象一下，${node.mainPoints?.[0] || '这个概念'}就像是一座桥梁，连接着理论与实践的两端。正如春天的种子需要阳光和雨露才能生根发芽，我们的理解也需要在实践中不断深化。举个生动的例子，就像是在黑暗中点亮一盏明灯，它照亮了前行的道路，让我们能够看清方向。这种体验就如同登山者攀登高峰，虽然过程艰辛，但当站在山顶俯瞰时，一切努力都变得有意义。因此，让我们用心感受这个过程，用行动诠释其价值。`,

      'data-driven': `${baseContent}根据最新的研究数据显示，${node.mainPoints?.[0] || '相关指标'}在过去三年中增长了约45%（数据来源：行业报告2024）。具体而言，在接受调查的1000家企业中，有78%表示采用了相关策略，其中62%的企业实现了显著的效益提升。进一步的统计分析表明，投资回报率平均达到了3.2倍，而用户满意度提高了30个百分点。这些客观数据充分证明了其在实际应用中的有效性，为我们的决策提供了坚实的依据。`,

      mixed: `${baseContent}${node.mainPoints?.[0] || '从多个角度来看'}，这个主题值得我们深入思考。一方面，数据显示相关应用正在快速增长，市场规模已达数十亿元；另一方面，从用户体验的角度来看，它就像是为人们打开了一扇新的大门，带来了前所未有的便利。通过详细分析，我们可以发现其核心价值在于平衡效率与质量，在实践中找到最佳的平衡点。综上所述，无论是从理论还是实践角度，都具有重要的参考价值。`,
    };

    return strategyContent[strategy] || strategyContent.concise;
  }

  /**
   * 重新生成段落版本
   */
  async regenerateParagraph(
    paragraphId: string,
    versionIndex: number,
    adjustments: RegenerationAdjustments
  ): Promise<{ content: string; metrics: ParagraphMetrics }> {
    console.log('🔄 [Paragraph] Regenerating version:', {
      paragraphId,
      versionIndex,
      adjustments,
    });

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/brainstorm/paragraph/${paragraphId}/regenerate`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            version_index: versionIndex,
            adjustments,
          }),
        }
      );

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      console.log('✅ [Paragraph] Regeneration completed');
      return data;
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error);
      console.error(`❌ [Paragraph] Failed to regenerate: ${errorMsg}`);
      // 返回Mock数据
      return {
        content: '这是重新生成的段落内容，已根据您的调整要求进行了优化。内容更加符合预期的风格和长度要求。',
        metrics: {
          relevance: 85,
          readability: 80,
          originality: 75,
          coherence: 88,
        },
      };
    }
  }

  /**
   * 混合多个版本的片段
   */
  async mixVersions(paragraphId: string, mixSelections: MixSelection[]): Promise<string> {
    console.log('🎨 [Paragraph] Mixing versions:', {
      paragraphId,
      selectionsCount: mixSelections.length,
    });

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/brainstorm/paragraph/${paragraphId}/mix`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            mix: mixSelections,
          }),
        }
      );

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      console.log('✅ [Paragraph] Mixing completed');
      return data.mixed_content;
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error);
      console.error(`❌ [Paragraph] Failed to mix versions: ${errorMsg}`);
      // 返回简单合并的结果
      return mixSelections.map((sel) => sel.text).join('');
    }
  }

  /**
   * 评估段落质量
   */
  async evaluateParagraph(content: string, context: {
    title: string;
    previousContent: string[];
  }): Promise<ParagraphMetrics> {
    try {
      const response = await fetch(`${this.baseUrl}/api/v1/brainstorm/paragraph/evaluate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          content,
          context,
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      return data.metrics;
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error);
      console.error(`❌ [Paragraph] Failed to evaluate: ${errorMsg}`);
      // 返回Mock评分
      return {
        relevance: 80,
        readability: 75,
        originality: 70,
        coherence: 85,
      };
    }
  }

  /**
   * 获取段落建议
   */
  async getParagraphSuggestions(
    content: string,
    context: {
      title: string;
      previousContent: string[];
      nextTitle?: string;
    }
  ): Promise<string[]> {
    try {
      const response = await fetch(`${this.baseUrl}/api/v1/brainstorm/paragraph/suggestions`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          content,
          context,
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      const data = await response.json();
      return data.suggestions;
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error);
      console.error(`❌ [Paragraph] Failed to get suggestions: ${errorMsg}`);
      // 返回Mock建议
      return [
        '可以添加具体的案例来增强说服力',
        '建议在段落结尾添加过渡语句',
        '考虑引用权威数据支持观点',
      ];
    }
  }

  /**
   * 关闭所有活跃连接
   */
  closeAllConnections(): void {
    this.activeConnections.forEach((ws) => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.close();
      }
    });
    this.activeConnections.clear();
    console.log('🔌 [Paragraph] All connections closed');
  }
}

export const paragraphGeneratorService = new ParagraphGeneratorService();
